package com.pickgliss.utils
{
	import com.pickgliss.geom.InnerRectangle;
	import com.pickgliss.toplevel.StageReferance;
	import com.pickgliss.ui.core.Component;
	import com.pickgliss.ui.image.Image;
	import com.pickgliss.ui.text.FilterFrameText;
	import com.pickgliss.ui.text.GradientText;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.InteractiveObject;
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.ui.Mouse;
	import flash.ui.MouseCursorData;
	import flash.utils.ByteArray;

	/**
	 * 
	 * @author Herman
	 * 
	 */	
	public final class DisplayUtils
	{
		private static const ZERO_POINT:Point = new Point(0, 0);
		
		
		/**
		 * 将显示对象移出舞台 
		 * @param args 需要移除舞台的对象
		 * @return 返回第一个对象
		 * 
		 */	
		public static function removeDisplay(...args):DisplayObject{
			for each(var display:DisplayObject in args){
				if(display && display.parent)display.parent.removeChild(display);
			}
			return args[0];
		}
		
		/**
		 * 
		 * @param $width 矩形的宽
		 * @param $height 矩形的高
		 * @param target : 绘制矩形的shape
		 * @return 创建完成的shape
		 * 
		 */		
		public static function drawRectShape($width:Number,$height:Number,target:Shape = null):Shape
		{
			var sp:Shape;
			if(target == null)
			{
				sp = new Shape();
			}else
			{
				sp = target;
			}
			sp.graphics.clear();
			sp.graphics.beginFill(0xFF0000,1);
			sp.graphics.drawRect(0,0,$width,$height);
			sp.graphics.endFill();
			return sp;
		}
		/**
		 * 绘制文本的shape
		 * @param 目标文本框
		 * @return 文本的shape
		 * 
		 */		
		public static function drawTextShape(sourceTextField:TextField):DisplayObject
		{
			var textBitmapData:BitmapData = new BitmapData(sourceTextField.width,sourceTextField.height,true,0xff0000);
			textBitmapData.draw(sourceTextField);
			var textGraphics:Shape=new Shape();
			textGraphics.cacheAsBitmap = true;
			for (var i:uint=0; i<textBitmapData.width; i++) {
				for (var j:uint=0; j<textBitmapData.height; j++) {
					var col:uint=textBitmapData.getPixel32(i,j);
					var alphaChannel:uint = col >> 24 & 0xFF;
					var alphaValue:Number = alphaChannel/0xFF;
					if (col > 0) {
						textGraphics.graphics.beginFill(0x000000,alphaValue);
						textGraphics.graphics.drawCircle(i,j,1);
					}
				}
			}
			return textGraphics;
		}
		/**
		 * 检查点是否在显示范围之内
		 * @param point : 需要检查的点
		 * @param parent : 此点所参考的父级，如果为stage可以不传
		 * @return point是否在显示范围之内
		 * 
		 */		
		public static function isInTheStage(point:Point,parent:DisplayObjectContainer = null):Boolean
		{
			var stagePoint:Point = point;
			if(parent)
			{
				stagePoint = parent.localToGlobal(point);
			}
			if(stagePoint.x < 0 || stagePoint.y < 0 || stagePoint.x > StageReferance.stageWidth || stagePoint.y > StageReferance.stageHeight) 
			{
				return false;
			}
			return true;
		}
		
		public static function layoutDisplayWithInnerRect(com:DisplayObject,innerRect:InnerRectangle,width:int,height:int):void
		{
			if(innerRect == null)return;
			if(com is Component)Component(com).beginChanges();
			var rect:Rectangle = innerRect.getInnerRect(width,height);
			com.x = rect.x;
			com.y = rect.y;
			com.width = rect.width;
			com.height = rect.height;
			if(com is Component)Component(com).commitChanges();
		}
		
		public static function setFrame(display:DisplayObject,frameIndex:int):void
		{
			if(display is Image)
			{
				Image(display).setFrame(frameIndex);
			}else if(display is MovieClip)
			{
				MovieClip(display).gotoAndStop(frameIndex);
			}else if(display is FilterFrameText)
			{
				FilterFrameText(display).setFrame(frameIndex);
			}else if(display is GradientText)
			{
				GradientText(display).setFrame(frameIndex);
			}
			return;
		}
		
		public static function setDisplayObjectNotEnable(display:DisplayObject):void
		{
			if(display is InteractiveObject)
			{
				InteractiveObject(display).mouseEnabled = false;
			}
			if(display is DisplayObjectContainer)
			{
				DisplayObjectContainer(display).mouseChildren = false;
				DisplayObjectContainer(display).mouseEnabled = false;
			}
		}
		
		public static function getTextFieldLineHeight(field:TextField):int
		{
			return field.getLineMetrics(0).height;
		}
		
		public static function getTextFieldCareLinePosY(field:TextField):Number
		{
			var lastCareCharIndex:int = field.caretIndex-1;
			var charCode:int = field.text.charCodeAt(lastCareCharIndex);
			var lastCareCharlineIndex:int = field.getLineIndexOfChar(lastCareCharIndex);
			var careCharLineIndex:int = 0;
			if(charCode == 13)
			{
				careCharLineIndex = lastCareCharlineIndex+1;
			}else
			{
				careCharLineIndex = lastCareCharlineIndex;
			}
			return getTextFieldLineHeight(field)*careCharLineIndex;
		}
		
		public static function getTextFieldCareLinePosX(field:TextField):Number
		{
			var lastCareCharIndex:int = field.caretIndex-1;
			var lastCharPos:Rectangle = field.getCharBoundaries(lastCareCharIndex);
			if(lastCharPos == null)return 0;
			return lastCharPos.x+lastCharPos.width;
		}
		
		public static function getVisibleSize (o:DisplayObject):Rectangle 
		{
			var bitmapDataSize:int = 2000;
			var bounds:Rectangle;
			var bitmapData:BitmapData = new BitmapData(bitmapDataSize, 
				bitmapDataSize,
				true,
				0);
			bitmapData.draw(o);
			bounds = bitmapData.getColorBoundsRect( 0xFF000000, 0x00000000, false );
			bitmapData.dispose(); 
			var retultRect:Rectangle = new Rectangle(bounds.x,bounds.y,bounds.x + bounds.width,bounds.y + bounds.height);
			return retultRect;
		}
		
		public static function getTextFieldMaxLineWidth(value:String,format:TextFormat,isHtmlText:Boolean):Number
		{
			var textField:TextField = new TextField();
			textField.autoSize = TextFieldAutoSize.LEFT;
			var linesText:Array
			if(isHtmlText)
			{
				value = value.replace("<BR>","\n");
				value = value.replace("<Br>","\n");
				value = value.replace("<bR>","\n");
				value = value.replace("<br>","\n");
			}
			linesText = value.split("\n");
			var maxWidth:Number = 0;
			for (var i:int = 0; i<linesText.length; i++)
			{
				if(isHtmlText)
				{
					textField.htmlText = linesText[i];
				}else
				{
					textField.text = linesText[i];
					textField.setTextFormat(format);
				}
				maxWidth = Math.max(maxWidth,textField.width);
			}
			return maxWidth+2;
		}
		
		public static function isTargetOrContain(target:DisplayObject,container:DisplayObject):Boolean
		{
			if(target == null)return false;
			if (target == container)
			{
				return true;
			}
			if (container is DisplayObjectContainer)
			{
				return DisplayObjectContainer(container).contains(target);
			}
			return false;
		}
		
		public static function getPointFromObject(pt:Point,pointInDisplay:DisplayObject,targetDisplay:DisplayObject):Point
		{
			var pt:Point = pointInDisplay.localToGlobal(pt);
			var targetLocalPoint:Point = targetDisplay.globalToLocal(pt);
			return targetLocalPoint;
		}
		
		public static function clearChildren(container:Sprite):void
		{
			while(container.numChildren > 0)
			{
				container.removeChildAt(0);
			}
		}
		
		public static function getDisplayBitmapData(display:DisplayObject):BitmapData
		{
			if(display is Bitmap)
			{
				return Bitmap(display).bitmapData;
			}
			var bmd:BitmapData = new BitmapData(display.width, display.height,true,0);
			bmd.draw(display);
			return bmd;
		}
		
		public static function localizePoint(to:DisplayObject, from:DisplayObject, p:Point = null):Point {
			return to.globalToLocal(from.localToGlobal(p ? p : new Point(0, 0)));
		}
		
		public static function setDisplayPos(display:DisplayObject,pos:Point):void
		{
			display.x = pos.x;
			display.y = pos.y;
		}
		
		public static function changeSize(obj:DisplayObject, w:int,h:int):void
		{
			obj.width = w;
			obj.height = h;
		}
		
		public static function horizontalArrange(obj:Sprite, column:int = 1, hSpace:Number = 0, vSpace:Number = 0):void
		{
			var n:int = 0;
			var posX:int = ZERO_POINT.x;
			var posY:int = ZERO_POINT.y;
			var tempWidth:int = 0;
			var tempHeight:int = 0;
			var rowNum:int = Math.ceil(obj.numChildren/column);
			for(var i:int = 0; i<rowNum; i++)
			{
				var maxHeight:int = 0;
				for(var j:int = 0; j<column; j++)
				{
					var ch:DisplayObject = obj.getChildAt(n++);
					ch.x = posX;
					ch.y = posY;
					tempWidth = Math.max(tempWidth,posX + ch.width);
					tempHeight = Math.max(tempHeight,posY+ch.height);
					posX += (ch.width + hSpace);
					if(maxHeight < ch.height)
					{
						maxHeight = ch.height;
					}
					if(n>=obj.numChildren)
					{
						changeSize(obj, tempWidth,tempHeight);
						return;
					}
				}
				posX = ZERO_POINT.x;
				posY += (maxHeight + vSpace);
			}
			changeSize(obj, tempWidth,tempHeight);
		}
		
		public static function verticalArrange(obj:Sprite, column:int = 1, hSpace:Number = 0, vSpace:Number = 0):void
		{
			var n:int = 0;
			var posX:int = ZERO_POINT.x;
			var posY:int = ZERO_POINT.y;
			var tempWidth:int = 0;
			var tempHeight:int = 0;
			var rowNum:int = Math.ceil(obj.numChildren/column);
			for(var i:int = 0; i<rowNum; i++)
			{
				var maxWidth:int = 0;
				for(var j:int = 0; j<column; j++)
				{
					var ch:DisplayObject = obj.getChildAt(n++);
					ch.x = posX;
					ch.y = posY;
					tempWidth = Math.max(tempWidth,posX + ch.width);
					tempHeight = Math.max(tempHeight,posY+ch.height);
					posY += (ch.height + vSpace);
					if(maxWidth < ch.width)
					{
						maxWidth = ch.width;
					}
					if(n>=obj.numChildren)
					{
						changeSize(obj, tempWidth,tempHeight);
						return;
					}
				}
				posX += (maxWidth + hSpace);
				posY = ZERO_POINT.y;
			}
			changeSize(obj,tempWidth,tempHeight);
		}
		
		public static function registMouseCursor(name:String,asset:*,hotPoint:Point = null):void
		{
			var vector:Vector.<BitmapData>;
			if(asset is Class)asset = new asset();
			
			if(asset is Bitmap)
			{
				vector = new Vector.<BitmapData>();
				vector.push(asset.bitmapData);
			}else if(asset is BitmapData)
			{
				vector = new Vector.<BitmapData>();
				vector.push(asset);
			}else if(asset is Vector.<BitmapData>)
			{
				vector = asset;
			}else
			{
				trace("register mouse cursor error");
			}
			
			if(hotPoint == null)
			{
				hotPoint = new Point(vector[0].width/2,vector[0].height/2);
			}
			
			var cursorData:MouseCursorData = new MouseCursorData();
			cursorData.data = vector;
			cursorData.hotSpot = hotPoint;
			Mouse.registerCursor(name,cursorData);
		}
		
		public static function centerDisplay(target:DisplayObject,parent:DisplayObject):void
		{
			target.x = (parent.width-target.width)/2;
			target.y = (parent.height-target.height)/2;
		}
		
		public static function readFromPngx(fileIn:ByteArray,isFlashFormat:Boolean = false):ByteArray
		{
			isFlashFormat ? fileIn.position = 45 : fileIn.position = 0 ;
			if (fileIn.readUnsignedInt() != 0x89504e47) return null;
			if (fileIn.readUnsignedInt() != 0x0D0A1A0A) return null;
			var chunks:Array = []; 
			var length:int = 0; 
			var type:String = "";
			do 
			{ 
				length = fileIn.readUnsignedInt(); 
				type = fileIn.readUTFBytes(4);
				
				if(type == "IEND")
				{
					if(length == 0)
					{
						return null;
					}else
					{
						var result:ByteArray = new ByteArray();
						result.writeBytes(fileIn,fileIn.position,length);
						return result;
					}
				}
				fileIn.position += length + 4; 
			}while (type != "IEND"); 
			return null;
		}
		
		public function DisplayUtils()
		{
		}
	}
}